<!DOCTYPE html>
<html>
<head>
    <title>Water Jet Impacting Coal Seam</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="800" height="550"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // General settings
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 2;
        ctx.font = '22px Arial';
        
        const centerY = 200;
        const jetHalfDiameter = 20;

        // Function to draw an arrowhead
        function drawArrowhead(x, y, angle) {
            const headLength = 8;
            ctx.save();
            ctx.translate(x, y);
            ctx.rotate(angle);
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(-headLength, -headLength / 2);
            ctx.moveTo(0, 0);
            ctx.lineTo(-headLength, headLength / 2);
            ctx.stroke();
            ctx.restore();
        }

        // 1. Draw the Nozzle
        const nozzleOuterWideHalf = 35;
        const nozzleOuterNarrowHalf = 30;
        const nozzleInnerHalf = 10;
        
        const startX = 50;
        const widePartEndX = 150;
        const taperEndX = 180;
        const narrowPartEndX = 350;

        ctx.beginPath();
        // Top outline
        ctx.moveTo(startX, centerY - nozzleOuterWideHalf);
        ctx.lineTo(widePartEndX, centerY - nozzleOuterWideHalf);
        ctx.lineTo(taperEndX, centerY - nozzleOuterNarrowHalf);
        ctx.lineTo(narrowPartEndX, centerY - nozzleOuterNarrowHalf);
        // Bottom outline
        ctx.moveTo(startX, centerY + nozzleOuterWideHalf);
        ctx.lineTo(widePartEndX, centerY + nozzleOuterWideHalf);
        ctx.lineTo(taperEndX, centerY + nozzleOuterNarrowHalf);
        ctx.lineTo(narrowPartEndX, centerY + nozzleOuterNarrowHalf);
        
        // Inner channel outline
        ctx.moveTo(startX, centerY - nozzleInnerHalf);
        ctx.lineTo(narrowPartEndX, centerY - nozzleInnerHalf);
        ctx.moveTo(startX, centerY + nozzleInnerHalf);
        ctx.lineTo(narrowPartEndX, centerY + nozzleInnerHalf);
        ctx.stroke();

        // Hatching for cross-section
        ctx.save();
        ctx.lineWidth = 1;
        // Top section
        for (let x = startX + 5; x < narrowPartEndX; x += 10) {
            let y1, y2;
            if (x < widePartEndX) {
                y1 = centerY - nozzleOuterWideHalf;
                y2 = centerY - nozzleInnerHalf;
            } else if (x < taperEndX) {
                const ratio = (x - widePartEndX) / (taperEndX - widePartEndX);
                y1 = centerY - (nozzleOuterWideHalf - (nozzleOuterWideHalf - nozzleOuterNarrowHalf) * ratio);
                y2 = centerY - nozzleInnerHalf;
            } else {
                y1 = centerY - nozzleOuterNarrowHalf;
                y2 = centerY - nozzleInnerHalf;
            }
            ctx.beginPath();
            ctx.moveTo(x, y1);
            ctx.lineTo(x + (y2 - y1), y2);
            ctx.stroke();
        }
        // Bottom section
        for (let x = startX + 5; x < narrowPartEndX; x += 10) {
            let y1, y2;
             if (x < widePartEndX) {
                y1 = centerY + nozzleOuterWideHalf;
                y2 = centerY + nozzleInnerHalf;
            } else if (x < taperEndX) {
                const ratio = (x - widePartEndX) / (taperEndX - widePartEndX);
                y1 = centerY + (nozzleOuterWideHalf - (nozzleOuterWideHalf - nozzleOuterNarrowHalf) * ratio);
                y2 = centerY + nozzleInnerHalf;
            } else {
                y1 = centerY + nozzleOuterNarrowHalf;
                y2 = centerY + nozzleInnerHalf;
            }
            ctx.beginPath();
            ctx.moveTo(x, y1);
            ctx.lineTo(x - (y1-y2), y2);
            ctx.stroke();
        }
        ctx.restore();

        // 2. Draw the Water Stream
        const streamStartX = narrowPartEndX;
        const streamEndX = 550;
        
        // Center dashed line
        ctx.save();
        ctx.setLineDash([8, 6]);
        ctx.beginPath();
        ctx.moveTo(startX, centerY);
        ctx.lineTo(streamEndX, centerY);
        ctx.stroke();
        ctx.restore();

        // Stream outer lines (emerging from inner part of nozzle)
        ctx.beginPath();
        ctx.moveTo(narrowPartEndX, centerY - nozzleInnerHalf);
        ctx.lineTo(streamEndX, centerY - nozzleInnerHalf);
        ctx.moveTo(narrowPartEndX, centerY + nozzleInnerHalf);
        ctx.lineTo(streamEndX, centerY + nozzleInnerHalf);
        ctx.stroke();
        
        // 3. Draw Dimension 'D'
        const dimX = 30;
        ctx.beginPath();
        ctx.moveTo(dimX, centerY - jetHalfDiameter);
        ctx.lineTo(dimX, centerY + jetHalfDiameter);
        ctx.stroke();
        drawArrowhead(dimX, centerY - jetHalfDiameter, -Math.PI / 2);
        drawArrowhead(dimX, centerY + jetHalfDiameter, Math.PI / 2);
        ctx.fillText('D', dimX - 25, centerY + 8);

        // 4. Draw Velocity 'v'
        ctx.font = 'italic 24px Times New Roman';
        ctx.fillText('v', 450, centerY - 40);
        ctx.font = '22px Arial'; // Reset font

        // 5. Draw the Coal Seam
        const coalX = streamEndX;
        ctx.fillStyle = '#404040';
        ctx.beginPath();
        ctx.moveTo(coalX, 80);
        ctx.quadraticCurveTo(coalX + 20, 70, coalX + 60, 85);
        ctx.quadraticCurveTo(coalX + 100, 100, coalX + 90, 140);
        ctx.quadraticCurveTo(coalX + 110, 180, coalX + 80, 200); // impact area
        ctx.quadraticCurveTo(coalX + 120, 210, coalX + 130, 250);
        ctx.quadraticCurveTo(coalX + 150, 280, coalX + 120, 310);
        ctx.quadraticCurveTo(coalX + 90, 350, coalX + 100, 380);
        ctx.quadraticCurveTo(coalX + 80, 420, coalX, 410);
        ctx.closePath();
        ctx.fill();

        // 6. Draw debris and details
        ctx.lineWidth = 1.5;
        // Near impact point
        ctx.beginPath();
        ctx.moveTo(coalX - 5, 220);
        ctx.lineTo(coalX - 20, 225);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(coalX, 230);
        ctx.arc(coalX-15, 235, 8, 0, Math.PI);
        ctx.stroke();

        // Debris below
        ctx.beginPath();
        ctx.arc(coalX + 20, 270, 8, 0, 2 * Math.PI);
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(coalX + 15, 290);
        ctx.lineTo(coalX + 10, 305);
        ctx.lineTo(coalX + 25, 300);
        ctx.closePath();
        ctx.fill();

        ctx.beginPath();
        ctx.arc(coalX + 55, 300, 18, Math.PI * 0.2, Math.PI * 1.3);
        ctx.fill();

        ctx.beginPath();
        ctx.moveTo(coalX + 45, 320);
        ctx.lineTo(coalX + 48, 335);
        ctx.moveTo(coalX + 55, 322);
        ctx.lineTo(coalX + 58, 337);
        ctx.stroke();
        
        ctx.beginPath();
        ctx.moveTo(coalX + 70, 330);
        ctx.arc(coalX + 80, 350, 5, 0, 2 * Math.PI);
        ctx.stroke();
        
        ctx.beginPath();
        ctx.moveTo(coalX + 20, 360);
        ctx.arc(coalX + 30, 365, 12, Math.PI, Math.PI * 1.8);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(coalX + 35, 375);
        ctx.lineTo(coalX + 45, 385);
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(coalX + 70, 390);
        ctx.quadraticCurveTo(coalX + 85, 385, coalX + 90, 400);
        ctx.stroke();
        
        // Vertical lines indicating texture/structure
        ctx.beginPath();
        ctx.moveTo(coalX + 60, 240);
        ctx.lineTo(coalX + 60, 260);
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(coalX + 50, 245);
        ctx.lineTo(coalX + 52, 265);
        ctx.stroke();
        
        ctx.beginPath();
        ctx.moveTo(coalX + 80, 320);
        ctx.lineTo(coalX + 85, 340);
        ctx.moveTo(coalX + 88, 322);
        ctx.lineTo(coalX + 93, 342);
        ctx.stroke();
        
        // 7. Draw the text label at the bottom
        ctx.fillStyle = 'black';
        ctx.font = '24px KaiTi'; // A common font for Chinese characters
        ctx.textAlign = 'center';
        ctx.fillText('习题 2-5 图', canvas.width / 2, 520);

    </script>
</body>
</html>